using System;
using AntEater.ComponentModel.Configuration;
using System.Reflection;

namespace AntEater.Runtime.UI
{
    /// <summary>
    /// A provider for creating new presenters.
    /// </summary>
    public class PresenterProvider : IServiceProvider
    {
        private PresenterElementCollection _presenterConfiguration;

        /// <summary>
        /// Initializes a new instance of the <see cref="PresenterProvider"/> class.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="presenterConfiguration">The presenter configuration.</param>
        public PresenterProvider(PresenterContext context, PresenterElementCollection presenterConfiguration) {
            this._presenterConfiguration = presenterConfiguration;
            this._context = context;
        }

        private PresenterContext _context;

        /// <summary>
        /// Gets the context.
        /// </summary>
        /// <value>The context.</value>
        public PresenterContext Context {
            get { return _context; }
        }

        /// <summary>
        /// Gets the service object of the specified type.
        /// </summary>
        /// <param name="serviceType">An object that specifies the type of service object to get.</param>
        /// <returns>
        /// A service object of type serviceType.-or- null if there is no service object of type serviceType.
        /// </returns>
        public object GetService(Type serviceType) {

            if (serviceType == null) { throw new ArgumentNullException("serviceType"); }

            IPresenter presenter = null;

            // Read the presenter type of the specified service interface from the configuration
            PresenterElement element = _presenterConfiguration[serviceType.Name];

            // Load the assembly and get the type
            Assembly assembly = Assembly.Load(element.Assembly);
            Type type = assembly.GetType(element.Type);

            // Create an instance of the type
            presenter = (IPresenter)Activator.CreateInstance(type);

            //Initialize the presenter with the current context
            if (presenter != null) {
                presenter.Initialize(this.Context);
            }
         
            return presenter;
            
        }
    }
}
